package com.xframe.xdal.core.domain;




import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import com.xframe.xdal.core.util.XBeanUtil;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * 功能描述: LinkedHashMap扩展动态实体对象 基类
 *
 * @author xufeng
 * @version 1.0
 * @date 2023-03-20
 */
public class XDynamicDict extends LinkedHashMap<String, Object>{

    static final int DEFAULT_CAPACITY = 16;
    static final float DEFAULT_LOAD_FACTOR = 0.75F;


    public static XDynamicDict create() {
        return new XDynamicDict();
    }


    public static <T> XDynamicDict parse(T bean) {
        return create().parseBean(bean);
    }

    public XDynamicDict() {
        this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
    }

    public XDynamicDict(int initialCapacity) {

        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    public XDynamicDict(Map<String, Object> m) {

        super((Map)(null == m ? new HashMap() : m));
    }

    public XDynamicDict(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);
    }



    public <T> XDynamicDict parseBean(T bean) {
        Assert.notNull(bean, "bean must be not null", new Object[0]);
        this.putAll(XBeanUtil.beanToMap(bean));
        return this;
    }

    public XDynamicDict set(String attr, Object value) {
        this.put(attr, value);
        return this;
    }

    public XDynamicDict setIgnoreNull(String attr, Object value) {
        if (null != attr && null != value) {
            this.set(attr, value);
        }
        return this;
    }

    public <T> T getBean(String attr) {
        return this.get(attr, null);
    }

    public <T> T get(String attr, T defaultValue) {
        Object result = this.get(attr);
        return result != null ? (T) result : defaultValue;
    }

    public void putAll(Map<? extends String, ?> m) {
        m.forEach(this::put);
    }

    public XDynamicDict clone() {
        return (XDynamicDict)super.clone();
    }


    public String getStr(String attr) {
        return Convert.toStr(this.get(attr), (String)null);
    }

    public Integer getInt(String attr) {
        return Convert.toInt(this.get(attr), (Integer)null);
    }

    public Long getLong(String attr) {
        return Convert.toLong(this.get(attr), (Long)null);
    }

    public Float getFloat(String attr) {
        return Convert.toFloat(this.get(attr), (Float)null);
    }

    public Short getShort(String attr) {
        return Convert.toShort(this.get(attr), (Short)null);
    }

    public Character getChar(String attr) {
        return Convert.toChar(this.get(attr), (Character)null);
    }

    public Double getDouble(String attr) {
        return Convert.toDouble(this.get(attr), (Double)null);
    }

    public Byte getByte(String attr) {
        return Convert.toByte(this.get(attr), (Byte)null);
    }

    public Boolean getBool(String attr) {
        return Convert.toBool(this.get(attr), (Boolean)null);
    }

    public BigDecimal getBigDecimal(String attr) {
        return Convert.toBigDecimal(this.get(attr));
    }

    public BigInteger getBigInteger(String attr) {
        return Convert.toBigInteger(this.get(attr));
    }

    public <E extends Enum<E>> E getEnum(Class<E> clazz, String key) {
        return Convert.toEnum(clazz, this.get(key));
    }

    public byte[] getBytes(String attr) {
        return (byte[])this.get(attr, (Object)null);
    }

    public Date getDate(String attr) {
        return (Date)this.get(attr, (Object)null);
    }

    public Time getTime(String attr) {
        return (Time)this.get(attr, (Object)null);
    }

    public Timestamp getTimestamp(String attr) {
        return (Timestamp)this.get(attr, (Object)null);
    }

    public Number getNumber(String attr) {
        return (Number)this.get(attr, (Object)null);
    }
}
